package com.CampusForum.community.service.impl;

import com.CampusForum.community.dao.LoginTicketMapper;
import com.CampusForum.community.dao.UserMapper;
import com.CampusForum.community.entity.LoginTicket;
import com.CampusForum.community.entity.User;
import com.CampusForum.community.service.UserService;
import com.CampusForum.community.util.CommunityConstant;
import com.CampusForum.community.util.CommunityUtil;
import com.CampusForum.community.util.HostHolder;
import com.CampusForum.community.util.MailClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService, CommunityConstant {
    @Autowired
    private MailClient mailClient;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TemplateEngine templateEngine;
    @Autowired
    private LoginTicketMapper loginTicketMapper;
    @Value("${header.url.front}")
    private String headerUrl;
    @Value("${community.domain}")
    private String domain;
    @Autowired
    private HostHolder hostHolder;

    @Override
    public User getUserById(int userId) {
        return userMapper.getById(userId);
    }

    @Override
    public Map<String, Object> register(User user) {
        Map<String, Object> map = new HashMap<>();
        if (user == null) {
            throw new IllegalArgumentException("参数不能为空");
        }
        // usernameMsg passwordMsg emailMsg
        if (StringUtils.isBlank(user.getUsername())) {
            map.put("usernameMsg", "账号为空");
            return map;
        }
        if (StringUtils.isBlank(user.getPassword())) {
            map.put("passwordMsg", "密码为空");
            return map;
        }
        if (StringUtils.isBlank(user.getEmail())) {
            map.put("emailMsg", "邮箱为空");
            return map;
        }
        // 检测账号和邮箱是否已经注册
        // 账号已存在
        if (userMapper.selectByName(user.getUsername()) != null) {
            map.put("usernameMsg", "账号已注册");
            return map;
        }
        // 邮箱已存在
        if (userMapper.selectByEmail(user.getEmail()) != null) {
            map.put("emailMsg", "邮箱已注册");
            return map;
        }
        User u = new User();
        u.setUsername(user.getUsername());
        // 设置盐值, 生成长度是5的随机值
        u.setSalt(CommunityUtil.generateUUID().substring(0, 5));
        // 密码+盐值 再进行md5加密
        u.setPassword(CommunityUtil.md5(user.getPassword() + u.getSalt()));
        u.setEmail(user.getEmail());
        u.setType(0);
        u.setStatus(0);
        u.setActivationCode(CommunityUtil.generateUUID());
        // 照片链接示例: http://images.nowcoder.com/head/21t.png
        u.setHeaderUrl(headerUrl+ RandomUtils.nextInt(0, 1000) +"t.png");
        u.setCreateTime(new Date());

        // 插入对象
        userMapper.insertUser(u);

        // 进行激活
        // 发送激活页面
        Context context = new Context();
        context.setVariable("email", u.getEmail());
        context.setVariable("url", domain+"/community/activation/"+u.getId()+"/"+u.getActivationCode());
        log.error("userId： "+u.getId());

        String sendHtml = templateEngine.process("/mail/activation", context);

        mailClient.sendMail(u.getEmail(), "激活账号", sendHtml);
        return map;
    }

    @Override
    public int activateUser(int userId, String activationCode) {
        User user = userMapper.getById(userId);
        if (user == null) {
            // 用户不存在
            return ACTIVATION_FAILURE;
        }
        if (user.getStatus() == 1) {
            // 用户重复激活
            return ACTIVATION_REPEAT;
        }
        if(! user.getActivationCode().equals(activationCode)) {
            // 激活码不对, 激活失败
            return ACTIVATION_FAILURE;
        }
        if(user.getStatus() == 0 && user.getActivationCode().equals(activationCode)) {
            userMapper.updateStatus(userId, 1);
            return ACTIVATION_SUCCESS;
        }
        return ACTIVATION_FAILURE;
    }

    @Override
    public Map<String, Object> login(String username, String password, boolean rememberme) {
        Map<String, Object> map = new HashMap<>();
        if(StringUtils.isBlank(username)) {
            map.put("usernameMsg", "账号为空");
            return map;
        }
        if(StringUtils.isBlank(password)) {
            map.put("passwordMsg", "密码为空");
            return map;
        }
        User user = userMapper.selectByName(username);
        if (user == null) {
            map.put("usernameMsg", "用户不存在, 请进行注册");
            return map;
        }
        password = CommunityUtil.md5(password+user.getSalt());
        if (!user.getPassword().equals(password)) {
            map.put("passwordMsg", "密码输入错误, 请重新输入");
            return map;
        }

        // 存储登录凭证
        LoginTicket loginTicket = new LoginTicket();
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(CommunityUtil.generateUUID());
        loginTicket.setStatus(0);
        int time;
        if (rememberme) {
            time = REMEMBER_EXPIRED_SECONDS;
        } else {
            time = DEFAULT_EXPIRED_SECONDS;
        }
        map.put("time", time);
        long currentTime = System.currentTimeMillis() + ((long)time) * 1000;
        loginTicket.setExpired(new Date(currentTime));
        map.put("ticket", loginTicket.getTicket());
        loginTicketMapper.insertLoginTicket(loginTicket);
        return map;
    }

    @Override
    public void logout(String ticket) {
        loginTicketMapper.updateStatus(ticket, 1);
    }

    @Override
    public void updateUserAvatar(User user, String headerUrl) {
        userMapper.updateHeader(user.getId(), headerUrl);
    }

    @Override
    public Map<String, Object> updatePassword(String oldPassword, String newPassword) {
        Map<String, Object> map = new HashMap<>();
        User user = hostHolder.getUser();
        oldPassword = CommunityUtil.md5(oldPassword + user.getSalt());
        if (! oldPassword.equals(user.getPassword())) {
            map.put("oldError", "原密码不正确!");
            return map;
        }
        if (StringUtils.isBlank(newPassword)) {
            map.put("newError", "新密码为空, 请重新输入!");
            return map;
        }
        if (newPassword.length() < 6) {
            map.put("newError", "新密码长度小于6, 请重新输入!");
            return map;
        }
        newPassword = CommunityUtil.md5(newPassword + user.getSalt());
        userMapper.updatePassword(user.getId(), newPassword);
        return map;
    }

    @Override
    public User getUserByName(String username) {
        return userMapper.getUserByName(username);
    }
}
